package com.cloud.utils;

import com.cloud.common.domain.map.DBScanNode;

import java.util.ArrayList;
import java.util.List;

/**
 * 坐标点聚类工具类
 *
 * @author yzj
 */
public class GisDBScanUtils<T extends DBScanNode> {

    /**
     * 聚合距离,单位/m
     */
    private double distance = 10;

    // 最低要求的寻找邻居数量
    private int minPoints = 1;

    public GisDBScanUtils() {
    }

    public GisDBScanUtils(double distance, int minPoints) {
        this.distance = distance;
        this.minPoints = minPoints;
    }

    public List<T> cluster(List<T> points) {
        List<T> clusters = new ArrayList<>();
        for (T point : points) {
            // 如果已经被标记,跳出本次循环
            if (point.getNodeMark()) {
                continue;
            }
            List<T> neighbors = getNeighbors(point, points);
            if (neighbors.size() > minPoints) {
                // 遍历所有邻居继续拓展找点
                point.setPolyNode(true);
            } else {
                point.setPolyNode(false);
            }
            point.setNodeMark(true);
            point.setPolyNum(neighbors.size());
            clusters.add(point);
        }
        return clusters;
    }

    /**
     * 找到所有的邻居
     *
     * @return
     */
    private List<T> getNeighbors(T point, List<T> points) {
        List<T> neighbors = new ArrayList<>();
        for (T neighbor : points) {
            if (neighbor.getNodeMark()) {
                continue;
            }
            double disFrom = GisPointUtils.getDistance(point.x, point.y, neighbor.x, neighbor.y);
            if (disFrom <= distance) {
                neighbor.setNodeMark(true);
                neighbors.add(neighbor);
            }
        }
        return neighbors;
    }

    public double getDistance() {
        return distance;
    }

    public int getMinPoints() {
        return minPoints;
    }

}
